package com.nicedistractions.roadtriptracker;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.database.Cursor;
import android.util.Log;

public class Uploader {
	
	private static final String TAG = "Uploader";
	private static final String URL = "http://nicedistractions.com/roadtrip/index.php/api/location";
	
	public static void postToTracker(long locationId, double lat, double longitude, float acc, double alt, float bearing, float speed, long time, DBHelper db) throws ClientProtocolException, IOException, JSONException {
		HttpClient httpclient = new DefaultHttpClient();
		HttpPost httppost = new HttpPost(URL);
		HttpResponse response = null;

		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
		nameValuePairs.add(new BasicNameValuePair("lat", String.valueOf(lat)));
		nameValuePairs.add(new BasicNameValuePair("long", String.valueOf(longitude)));
		nameValuePairs.add(new BasicNameValuePair("acc", String.valueOf(acc)));
		nameValuePairs.add(new BasicNameValuePair("alt", String.valueOf(alt)));
		nameValuePairs.add(new BasicNameValuePair("bear", String.valueOf(bearing)));
		nameValuePairs.add(new BasicNameValuePair("speed", String.valueOf(speed)));
		nameValuePairs.add(new BasicNameValuePair("time", String.valueOf(time)));
		httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
		
		Log.i(TAG, lat + " - " + longitude+ " - " + time);

		// Execute HTTP Post Request
		response = httpclient.execute(httppost);
		HttpEntity entity = response.getEntity();
		
		if (entity != null) {
			//If we got a result
			InputStream instream = entity.getContent();
			String result = convertStreamToString(instream);
			instream.close();
			Log.i(TAG, result);
			JSONObject json = new JSONObject(result);			

			if(json.getString("status").equalsIgnoreCase("success")) {
				//If it worked	
				long now = new Date().getTime();
				db.locationUploaded(locationId, now);
				Control.updateLastUpload(now);
			}
			else {
				//If it failed
			}
		}
	}
	
	/**
	 * Upload any ones that failed.
	 * @throws JSONException 
	 * @throws IOException 
	 * @throws ClientProtocolException 
	 */
	public static void uploadAll(DBHelper db) throws ClientProtocolException, IOException, JSONException {
		Cursor toUpload = db.getLocationsToUpload();
		toUpload.moveToFirst();
		
		while(!toUpload.isAfterLast()) {
			//For each location
			postToTracker(toUpload.getLong(toUpload.getColumnIndex(DBHelper.KEY_ROWID)), toUpload.getDouble(toUpload.getColumnIndex(DBHelper.KEY_LAT)), toUpload.getDouble(toUpload.getColumnIndex(DBHelper.KEY_LONG)), toUpload.getFloat(toUpload.getColumnIndex(DBHelper.KEY_ACC)), toUpload.getDouble(toUpload.getColumnIndex(DBHelper.KEY_ALT)), toUpload.getFloat(toUpload.getColumnIndex(DBHelper.KEY_BEAR)), toUpload.getFloat(toUpload.getColumnIndex(DBHelper.KEY_SPEED)), toUpload.getLong(toUpload.getColumnIndex(DBHelper.KEY_TIME)), db);
			toUpload.moveToNext();
		}
		toUpload.close();
	}
	
	/**
	 * To convert the InputStream to String we use the BufferedReader.readLine()
	 * method. We iterate until the BufferedReader return null which means
	 * there's no more data to read. Each line will appended to a StringBuilder
	 * and returned as String.
	 * 
	 * @param is
	 *            InputStream
	 * @return
	 */
	public static String convertStreamToString(InputStream is) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(is), 8*1024);
		StringBuilder sb = new StringBuilder();

		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}
}
